---
title: Astro v5로 업그레이드
description: How to upgrade your project to Astro v5.0.
sidebar:
  label: v5.0
i18nReady: true
---
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'
import { Steps } from '@astrojs/starlight/components';
import ReadMore from '~/components/ReadMore.astro'
import SourcePR from '~/components/SourcePR.astro'

이 가이드는 Astro v4에서 Astro v5로 마이그레이션하는 것을 도와줍니다.

더 오래된 프로젝트를 먼저 v4로 업그레이드해야 하나요? [이전 마이그레이션 가이드](/ko/guides/upgrade-to/v4/)를 참조하세요.

v4 문서를 보고 싶으신가요? [문서 사이트의 이전 버전(관리되지 않는 v4.16 스냅샷)](https://v4.docs.astro.build/)을 방문하세요.

## Astro 업그레이드

패키지 매니저를 사용하여 프로젝트의 Astro를 최신 버전으로 업데이트하세요:

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  # Astro와 공식 통합을 함께 업그레이드
  npx @astrojs/upgrade
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  # Astro와 공식 통합을 함께 업그레이드
  pnpm dlx @astrojs/upgrade
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  # Astro와 공식 통합을 함께 업그레이드
  yarn dlx @astrojs/upgrade
  ```
  </Fragment>
</PackageManagerTabs>

필요한 경우 [Astro 통합을 수동으로 업그레이드](/ko/guides/integrations-guide/#수동-업그레이드)할 수도 있으며, 프로젝트의 다른 종속성도 업그레이드해야 할 수 있습니다.

:::note[계속 진행해야 하나요?]
Astro를 업그레이드한 후에는 프로젝트를 전혀 수정할 필요가 없을 수도 있습니다!

하지만 오류나 예상치 못한 동작이 발견되면, 아래에서 업데이트가 필요할 수 있는 변경 사항을 확인하시기 바랍니다.
:::

Astro v5.0에는 [잠재적인 주요 변경 사항](#주요-변경-사항)과 함께 일부 기능의 제거 및 사용 중단이 포함되어 있습니다.

v5.0으로 업그레이드한 후 프로젝트가 예상대로 작동하지 않는 경우, 이 가이드를 통해 모든 주요 변경 사항과 코드베이스 업데이트 방법에 대한 개요를 확인하세요.

전체 릴리스 노트는 [Astro 변경 로그](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md)를 참조하세요.

## 종속성 업그레이드

Astro의 종속성에 대한 주요 업그레이드는 프로젝트에서 주요 변경 사항을 발생시킬 수 있습니다.

### Vite 6.0

Astro v5.0은 개발 서버와 프로덕션 번들러를 Vite v6.0으로 업그레이드하였습니다.

#### 무엇을 해야 하나요?

Vite 관련 플러그인, 설정 또는 API를 사용하고 있다면, [Vite 마이그레이션 가이드](https://ko.vite.dev/guide/migration.html)에서 주요 변경 사항을 확인하고 필요에 따라 프로젝트를 업그레이드하세요.

### `@astrojs/mdx`

<SourcePR number="11741" title="Cleanup unused JSX code"/>

Astro v4.x에서는 `@astrojs/mdx` 통합을 위한 JSX 처리를 Astro 내부에서 수행했습니다.

Astro v5.0에서는 JSX와 MDX를 처리하고 렌더링하는 책임을 `@astrojs/mdx` 패키지로 직접 이동했습니다. 이는 Astro 5.0이 더 이상 이전 버전의 MDX 통합과 호환되지 않는다는 것을 의미합니다.

#### 무엇을 해야 하나요?

프로젝트에 `.mdx` 파일이 포함되어 있다면, JSX가 통합에 의해 제대로 처리될 수 있도록 `@astrojs/mdx`를 최신 버전(v4.0.0)으로 업그레이드해야 합니다.

실험적인 [Astro 컨테이너 API](/ko/reference/container-reference/)와 함께 MDX 서버 렌더러를 사용하고 있다면, 새로운 위치를 반영하도록 import를 업데이트해야 합니다:

```ts del={1} ins={2}
import mdxRenderer from "astro/jsx/server.js";
import mdxRenderer from "@astrojs/mdx/server.js";
```

<ReadMore>[프로젝트에서 MDX를 사용](/ko/guides/integrations-guide/mdx/)하는 방법에 대해 자세히 알아보세요.</ReadMore>

## 레거시

다음 기능들은 이제 레거시로 간주됩니다. 정상적으로 작동하지만 더 이상 권장되지 않으며 유지보수 모드에 있습니다. 앞으로 개선될 예정이 없으며 문서도 업데이트되지 않을 것입니다. 이러한 기능들은 결국 더 이상 사용되지 않게 되며, 이후 완전히 제거될 것입니다.

### 레거시: v2.0 콘텐츠 컬렉션 API

Astro 4.x에서는 [Astro v2.0에서 처음 도입된 콘텐츠 컬렉션 API](https://astro.build/blog/introducing-content-collections/)를 사용하여 콘텐츠 컬렉션을 정의, 쿼리 및 렌더링했습니다. 모든 컬렉션 항목은 예약된 `src/content/` 폴더의 로컬 파일입니다. 또한 Astro의 [개별 페이지 작성을 제외하기 위한 파일 이름 규칙](/ko/guides/routing/#페이지-제외)이 콘텐츠 컬렉션 API에 내장되어 있습니다.

Astro 5.0은 여러 성능 향상과 추가 기능을 제공하는 콘텐츠 레이어 API를 사용하는 새로운 버전의 콘텐츠 컬렉션을 도입합니다. 이번 릴리스에서는 이전(레거시) 컬렉션과 새로운(콘텐츠 레이어 API) 컬렉션이 함께 존재할 수 있지만, 기존 레거시 컬렉션에 잠재적인 주요 변경 사항이 있을 수 있습니다.

또한 이번 릴리스에서는 라우트 구축을 방지하기 위해 컬렉션 항목 파일 이름 앞에 밑줄(`_`)을 붙이는 옵션이 제거되었습니다.

#### 무엇을 해야 하나요?

가능한 한 빨리 [기존 컬렉션을 새로운 콘텐츠 레이어 API로 변환](#기존-컬렉션-업데이트)하고 새로운 컬렉션을 만들 때도 콘텐츠 레이어 API를 사용하는 것을 권장합니다.

컬렉션을 변환할 수 없는 경우, [레거시 컬렉션의 주요 변경 사항](#레거시-content-및-data-컬렉션의-주요-변경-사항)을 참고하여 기존 컬렉션이 영향을 받는지, 업데이트가 필요한지 확인하시기 바랍니다.

현재 컬렉션을 변경할 수 없는 경우, [`legacy.collections` 플래그를 활성화](#legacycollections-플래그-활성화)하여 레거시 플래그가 더 이상 지원되지 않을 때까지 컬렉션을 현재 상태로 유지할 수 있습니다.

<ReadMore>업데이트된 [콘텐츠 컬렉션](/ko/guides/content-collections/)에 대해 자세히 알아보세요.</ReadMore>

##### 기존 컬렉션 업데이트

콘텐츠 레이어 API를 사용하기 위해 기존 콘텐츠 컬렉션(`type: 'content'` 또는 `type: 'data'`)을 업데이트하는 방법은 아래의 안내를 참고하세요.

<details>
<summary>컬렉션을 업데이트하는 단계별 안내</summary>

<Steps>

1. **콘텐츠 설정 파일 이동하기**. 이 파일은 더 이상 `src/content/` 폴더에 있지 않습니다. 이제 이 파일은 `src/content.config.ts`에 위치해야 합니다.

2. **컬렉션 정의 수정하기**. 업데이트된 컬렉션은 `loader`가 필요하며, 이는 컬렉션이 위치한 폴더인 `base`와 컬렉션 항목 파일들의 이름과 확장자를 매칭할 `pattern`을 지정합니다. (아래 예시를 상황에 맞게 수정해야 할 수 있습니다. [globster.xyz](https://globster.xyz/)에서 glob 패턴을 테스트해볼 수 있습니다.) 컬렉션을 선택하기 위한 `type` 옵션은 더 이상 제공되지 않습니다.

    ```ts ins={3,8} del={7}
    // src/content.config.ts
    import { defineCollection, z } from 'astro:content';
    import { glob } from 'astro/loaders';

    const blog = defineCollection({
      // 콘텐츠 레이어에서는 더 이상 `type`을 정의하지 않습니다
      type: 'content',
      loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/data/blog" }),
      schema: z.object({
        title: z.string(),
        description: z.string(),
        pubDate: z.coerce.date(),
        updatedDate: z.coerce.date().optional(),
      }),
    });
    ```
    
3. **`slug`를 `id`로 참조 변경하기**. 콘텐츠 레이어 컬렉션에는 예약된 `slug` 필드가 없습니다. 대신, 모든 업데이트된 컬렉션은 `id`를 가지게 됩니다:

    ```astro ins={7} del={6}
    // src/pages/[slug].astro
    ---
    export async function getStaticPaths() {
      const posts = await getCollection('blog');
      return posts.map((post) => ({
        params: { slug: post.slug },
        params: { slug: post.id },
        props: post,
      }));
    }
    ---
    ```
    변경된 `getStaticPaths()` 매개변수와 일치하도록 동적 라우팅 파일 이름도 업데이트 할 수 있습니다

4. **새로운 `render()` 함수로 전환하기**. 이제 항목들이 직렬화 가능한 일반 객체이므로 더 이상 `render()` 메서드를 가지지 않습니다. 대신, `astro:content`에서 `render()` 함수를 가져와야 합니다.

    ```astro title="src/pages/index.astro" ins=", render" del={6} ins={7}
    ---
    import { getEntry, render } from 'astro:content';

    const post = await getEntry('blog', params.slug);

    const { Content, headings } = await post.render();
    const { Content, headings } = await render(post);
    ---
    <Content />
    ```
</Steps>

</details>

##### 레거시 `content` 및 `data` 컬렉션의 주요 변경 사항

<SourcePR number="11976" title="Implement legacy collections using glob" />

기본적으로 이전 `type` 속성(`content` 또는 `data`)을 사용하고 `loader`를 정의하지 않는 컬렉션은 이제 콘텐츠 레이어 API의 내장 `glob()` 로더를 사용하여 내부적으로 구현되며, 추가적인 하위 호환성 처리가 포함됩니다.

또한, 콘텐츠 설정 파일을 원래 위치인 `src/content/config.ts`에 유지하기 위한 임시 하위 호환성이 존재합니다.

이러한 하위 호환성 구현은 레거시 컬렉션의 대부분의 기능을 에뮬레이션할 수 있으며, 코드를 업데이트하지 않아도 많은 레거시 컬렉션이 계속 작동할 수 있게 합니다. 하지만, **기존 컬렉션에 주요 변경 사항을 발생시킬 수 있는 몇 가지 차이점과 제한 사항이 있습니다**:
    
  - 이전 Astro 버전에서는 `src/content/config.ts`에 정의되지 않았더라도 `src/content/` 내 모든 폴더에 대해 컬렉션이 생성되었습니다. 이 동작은 이제 더 이상 사용되지 않으며, 컬렉션은 항상 `src/content.config.ts`에 정의되어야 합니다. 기존 컬렉션의 경우 빈 선언(예: `const blog = defineCollection({})`)만으로도 충분하며, Astro는 새로운 로딩 동작과 호환되는 방식으로 레거시 컬렉션을 암시적으로 정의할 것입니다.
  - 특별한 `layout` 필드는 Markdown 컬렉션 항목에서 지원되지 않습니다. 이 속성은 `src/pages/`에 위치한 독립 실행형 페이지 파일에만 사용되며 컬렉션 항목에는 사용되지 않을 가능성이 높습니다. 하지만 이 속성을 사용하고 있었다면, 이제 페이지 스타일링을 포함하는 동적 경로를 생성해야 합니다.
  - 생성된 컬렉션의 정렬 순서는 비결정적이며 플랫폼에 따라 다릅니다. 즉, `getCollection()`을 호출할 때 항목이 반환되는 순서가 이전과 다를 수 있습니다. 특정 순서가 필요한 경우 컬렉션 항목을 직접 정렬해야 합니다.
  - `image().refine()`은 지원되지 않습니다. 이미지의 속성을 검증해야 하는 경우 페이지나 컴포넌트에서 런타임에 이를 수행해야 합니다.
  - `getEntry(collection, key)`의 `key` 인자는 모든 항목에 대한 타입을 가지는 대신 `string`으로 타입이 지정됩니다.
  - 이전에는 `getEntry(collection, key)`에 key를 정적 문자열로 전달하여 호출할 때 반환 타입이 널러블하지 않았습니다. 이제 타입에 `undefined`가 포함되므로 결과를 사용하기 전에 항목이 정의되었는지 확인해야 하며, 그렇지 않으면 타입 오류가 발생합니다.

##### `legacy.collections` 플래그 활성화

<SourcePR number="11976" title="Implement legacy collections using glob" />

아직 기존 컬렉션을 업데이트할 준비가 되지 않았다면, [`legacy.collections`](/ko/reference/legacy-flags/) 플래그를 활성화하여 기존 컬렉션이 이전처럼 계속 작동하도록 할 수 있습니다.

## 더 이상 사용되지 않음

다음의 더 이상 사용되지 않는 기능들은 더 이상 지원되지 않으며 문서화되지 않습니다. 이에 따라 프로젝트를 업데이트하시기 바랍니다.

일부 더 이상 사용되지 않는 기능들은 완전히 제거될 때까지 일시적으로 계속 작동할 수 있습니다. 다른 기능들은 아무 효과 없이 조용히 무시되거나, 코드 업데이트를 요구하는 오류를 발생시킬 수 있습니다.

### 더 이상 사용되지 않음: `Astro.glob()`

<SourcePR number="11826" title="Deprecate glob"/>

Astro v4.x에서는 `.astro` 컴포넌트에서 `Astro.glob()`을 사용하여 프로젝트의 여러 파일을 쿼리할 수 있었습니다. 이는 몇 가지 제한사항(사용할 수 있는 위치, 성능 등)이 있었으며, 콘텐츠 컬렉션 API의 쿼리 함수나 Vite의 `import.meta.glob()`을 사용하는 것이 더 많은 기능과 유연성을 제공했습니다.

Astro 5.0에서는 `Astro.glob()` 대신 컬렉션을 쿼리하기 위한 `getCollection()`과 프로젝트의 다른 소스 파일을 쿼리하기 위한 `import.meta.glob()`을 사용하도록 변경되었습니다.

#### 무엇을 해야 하나요?

모든 `Astro.glob()` 사용을 `import.meta.glob()`로 교체하세요. `import.meta.glob()`는 더 이상 `Promise`를 반환하지 않으므로, 이에 따라 코드를 업데이트해야 할 수 있습니다. [glob 패턴](/ko/guides/imports/#glob-패턴)은 업데이트할 필요가 없습니다.

```astro title="src/pages/blog.astro" del={2} ins={3}
---
const posts = await Astro.glob('./posts/*.md');
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
---

{posts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
```

적절한 경우, 자체적으로 더 새롭고 성능이 좋은 쿼리 함수를 가진 [콘텐츠 컬렉션](/ko/guides/content-collections/)을 사용하여 콘텐츠를 구성하는 것을 고려해보세요.

또한 [`fast-glob`](https://www.npmjs.com/package/fast-glob)과 같은 NPM의 glob 패키지 사용을 고려해볼 수 있습니다.

<ReadMore>[`import.meta.glob`을 사용한 파일 가져오기](/ko/guides/imports/#importmetaglob)에 대해 자세히 알아보세요.</ReadMore>
 
### 더 이상 사용되지 않음: `functionPerRoute` (어댑터 API)

<SourcePR number="11714" title="Remove functionPerRoute option"/>

Astro v4.x에서는 프로젝트에 정의된 각 경로에 대해 별도의 파일을 생성하도록 선택할 수 있었으며, 이는 빌드 폴더에서 `src/pages/` 디렉터리를 미러링했습니다. 기본적으로 Astro는 각 요청에서 렌더링된 페이지를 생성하는 단일 `entry.mjs` 파일을 생성했습니다.

Astro v5.0은 기본 동작을 선택 해제하는 옵션을 제거합니다. 이 동작은 이제 표준이며 설정할 수 없습니다.

`adapterFeatures` 설정에서 `functionPerRoute` 속성을 제거하세요. 더 이상 사용할 수 없습니다.

```js title="my-adapter.mjs" del={10}
export default function createIntegration() {
  return {
    name: '@matthewp/my-adapter',
    hooks: {
      'astro:config:done': ({ setAdapter }) => {
        setAdapter({
          name: '@matthewp/my-adapter',
          serverEntrypoint: '@matthewp/my-adapter/server.js',
          adapterFeatures: {
              functionPerRoute: true
          }
        });
      },
    },
  };
}

```

<ReadMore>어댑터 통합을 구축하기 위한 [어댑터 API](/ko/reference/adapter-reference/)에 대해 자세히 알아보세요.</ReadMore>

### 더 이상 사용되지 않음: `astro:build:done` 훅의 `routes` (통합 API)

<SourcePR number="12329" title="feat(next): astro:routes:resolved"/>

Astro v4.x에서는 통합이 `astro:build:done` 훅에서 라우트에 접근했습니다.

Astro v5.0에서는 이 훅에 전달되는 `routes` 배열을 더 이상 사용하지 않습니다. 대신, `astro:config:done` 이전에 실행되고 개발 모드에서 라우트가 변경될 때마다 실행되는 새로운 `astro:routes:resolved` 훅을 제공합니다. 이는 빌드 중에만 사용할 수 있는 `distURL`을 제외하고 더 이상 사용되지 않는 `routes` 목록의 모든 속성을 가지고 있습니다.

#### 무엇을 해야 하나요?

`astro:build:done`에 전달된 모든 `routes` 인스턴스를 제거하고 새로운 `astro:routes:resolved` 훅으로 교체하세요. 새로 노출된 `assets` 맵에서 `distURL`에 접근하세요:

```js title="my-integration.mjs" ins={2,6-8,11,13-18} del={10}
const integration = () => {
    let routes
    return {
        name: 'my-integration',
        hooks: {
            'astro:routes:resolved': (params) => {
                routes = params.routes
            },
            'astro:build:done': ({
                routes
                assets
            }) => {
                for (const route of routes) {
                    const distURL = assets.get(route.pattern)
                    if (distURL) {
                        Object.assign(route, { distURL })
                    }
                }
                console.log(routes)
            }
        }
    }
}
```

<ReadMore>통합 구축을 위한 [통합 API `astro:routes:resolved` 훅](/ko/reference/integrations-reference/#astroroutesresolved)에 대해 자세히 알아보세요.</ReadMore>

## 제거됨

다음 기능들은 이제 코드베이스에서 완전히 제거되었으며 더 이상 사용할 수 없습니다. 이러한 기능 중 일부는 더 이상 사용되지 않게 된 후에도 프로젝트에서 계속 작동했을 수 있습니다. 다른 기능들은 아무 효과 없이 조용히 무시되었을 수 있습니다.

이제 이러한 제거된 기능이 포함된 프로젝트는 빌드할 수 없으며, 이러한 기능을 제거하라는 안내 문서도 더 이상 제공되지 않을 것입니다.

### 제거됨: Lit 통합

<SourcePR number="11680" title="Remove `@astrojs/lit`"/>

Astro v4.x에서 [Lit](https://lit.dev/)는 `@astrojs/lit` 패키지를 통해 코어에서 유지 관리하는 프레임워크 라이브러리였습니다.

Astro v5.0에서는 이 통합이 제거되었으며 5.x 이상 버전과의 호환성을 위한 추가 업데이트를 받지 않을 것입니다.

#### 무엇을 해야 하나요?

다음과 같이 클라이언트 측 스크립트 태그를 추가하여 클라이언트 컴포넌트에 계속 Lit를 사용할 수 있습니다:

```astro
<script>
  import "../components/MyTabs";
</script>

<my-tabs title="These are my tabs">...</my-tabs>
```

Lit 통합을 직접 유지 관리하는 데 관심이 있다면, [마지막으로 게시된 버전의 `@astrojs/lit`](https://github.com/withastro/astro/tree/astro%404.13.0/packages/integrations/lit)를 시작점으로 사용하고 관련 패키지를 업그레이드할 수 있습니다.

<ReadMore>[Astro의 공식 통합](/ko/guides/integrations-guide/)에 대해 자세히 알아보세요.</ReadMore>

### 제거됨: `hybrid` 렌더링 모드

<SourcePR number="11824" title="Merge output:hybrid and output:static" />

Astro v4.x에서는 세 가지 `output` 렌더링 모드를 제공했습니다: `'static'`, `'hybrid'`, 그리고 `'server'`

Astro v5.0은 `output: 'hybrid'`와 `output: 'static'` 설정을 하나의 설정(이제 `'static'`이라고 불림)으로 통합하며, 이는 이전의 hybrid 옵션과 동일한 방식으로 작동합니다.

서버 렌더링 페이지를 사용하기 위해 더 이상 Astro 구성에서 `output: 'hybrid'`를 지정할 필요가 없습니다. 새로운 `output: 'static'`에 이 기능이 포함되어 있습니다.

이제 Astro는 출력 설정을 변경하지 않고도 정적 사이트에서 사전 렌더링을 선택적으로 해제할 수 있게 합니다. 모든 페이지 경로나 엔드포인트에 `export const prerender = false`를 포함하면 사이트의 나머지 부분은 정적으로 생성되는 동안 해당 페이지는 필요할 때 서버에서 렌더링됩니다.

#### 무엇을 해야 하나요?

프로젝트에서 하이브리드 렌더링을 사용했다면, Astro 구성에서 이제 더 이상 존재하지 않는 `output: 'hybrid'` 옵션을 제거해야 합니다. 하지만 프로젝트의 다른 변경 사항은 필요하지 않으며, 주요 변경 사항도 없을 것입니다. 이전의 `'hybrid'` 동작이 이제 `'static'`이라는 새로운 이름으로 기본값이 되었습니다.

```js title="astro.config.mjs" del={4}
import { defineConfig } from "astro/config";

export default defineConfig({
  output: 'hybrid',
});
```

`output: 'static'`(기본값) 옵션을 사용하고 있었다면, 이전처럼 계속 사용할 수 있습니다. 기본적으로 모든 페이지는 계속 사전 렌더링되며 완전히 정적인 사이트를 가지게 될 것입니다. 프로젝트에 주요 변경 사항은 없을 것입니다.

프로젝트가 어떤 `output` 모드를 사용하든 서버 렌더링된 페이지가 있는 Astro 프로젝트를 배포하려면 여전히 어댑터가 필요합니다. 어댑터를 포함하지 않으면 개발 중에는 경고가, 빌드 시에는 오류가 발생합니다.

<ReadMore>[Astro의 요청 시 렌더링](/ko/guides/on-demand-rendering/)에 대해 자세히 알아보세요.</ReadMore>

### 제거됨: 라우트에서 동적 `prerender` 값 지원

<SourcePR number="11824" title="Merge output:hybrid and output:static" />

Astro 4.x에서는 환경 변수를 사용하여 라우트의 `prerender` 내보내기 값을 동적으로 설정할 수 있었습니다. (예: `export const prerender = import.meta.env.SOME_VAR`)

Astro v5.0에서는 `prerender` 내보내기의 동적 값 지원이 제거되었습니다. 정적 값인 `true` 및 `false`만 사용할 수 있습니다.

#### 무엇을 해야 하나요?

<Steps>

1. 라우트에서 모든 동적 `prerender` 내보내기를 제거합니다.

    ```astro title="src/pages/blog/[slug].astro" del={2}
    ---
    export const prerender = import.meta.env.SOME_VAR;
    ---
    ```

2. 동적이어야 하는 `prerender` 값을 설정하기 위해 `astro.config.mjs` 파일에서 Astro 통합의 `"astro:route:setup"` 훅을 사용합니다.

    ```js title="astro.config.mjs" {6-19}
    import { defineConfig } from 'astro/config';
    import { loadEnv } from 'vite';

    export default defineConfig({
      integrations: [
        {
          name: 'set-prerender',
          hooks: {
            'astro:route:setup': ({ route }) => {
              // .env 파일에서 환경 변수를 로드합니다. (필요한 경우)
              const { PRERENDER } = loadEnv(process.env.NODE_ENV, process.cwd(), '');
              // 파일 이름과 일치하는 라우트를 찾습니다.
              if (route.component.endsWith('/blog/[slug].astro')) {
                // 필요에 따라 라우트에 prerender 값을 설정합니다.
                route.prerender = PRERENDER;
              }
            },
          },
        }
      ],
    });
    ```

</Steps>

### 제거됨: Squoosh 이미지 서비스

<SourcePR number="11770" title="remove the squoosh image service"/>

Astro 4.x에서는 Sharp 대신 Squoosh를 사용하여 이미지를 변환하도록 `image.service: squooshImageService()`를 구성할 수 있었습니다. 하지만 기반이 되는 라이브러리인 `libsquoosh`는 더 이상 유지 관리되지 않으며 메모리와 성능 문제가 있습니다.

Astro 5.0은 Squoosh 이미지 최적화 서비스를 완전히 제거합니다.

#### 무엇을 해야 하나요?

내장 Sharp 이미지 서비스로 전환하려면, Astro 구성에서 `squooshImageService` 가져오기를 제거하세요. 기본적으로 `astro:assets`에 Sharp를 사용하게 됩니다.

```ts title="astro.config.mjs" del={1, 5-7}
import { squooshImageService } from "astro/config";
import { defineConfig } from "astro/config";

export default defineConfig({
 image: {
   service: squooshImageService()
 }
});
```

`pnpm`과 같은 엄격한 패키지 매니저를 사용하는 경우, Sharp가 Astro에 기본적으로 내장되어 있더라도 Sharp 이미지 서비스를 사용하기 위해 `sharp` 패키지를 수동으로 설치해야 할 수 있습니다.

어댑터가 Astro의 내장 Sharp 이미지 최적화를 지원하지 않는 경우, `<Image />` 및 `<Picture />` 컴포넌트를 사용할 수 있도록 [no-op 이미지 서비스를 구성](/ko/guides/images/#무작동-패스스루-서비스-구성)할 수 있습니다.

또는 Sharp 이미지 서비스를 사용할 수 없는 경우 [커뮤니티에서 유지 관리하는 Squoosh 이미지 서비스](https://github.com/Princesseuh/astro-image-service-squoosh)를 고려해볼 수 있습니다.

##### 어댑터

이전에 어댑터에서 Squoosh와의 호환성 상태를 명시했다면, 이제 어댑터 설정에서 이 정보를 제거해야 합니다.

```js title="my-adapter.mjs" del={2-4}
supportedAstroFeatures: {
  assets: {
    isSquooshCompatible: true
  }
}
```

<ReadMore>[기본 이미지 서비스 구성](/ko/guides/images/#기본-이미지-서비스)에 대해 자세히 알아보세요.</ReadMore>

### 제거됨: 일부 공개 타입

<SourcePR number="11715" title="Refactor/types"/>

Astro v4.x에서는 `@types/astro.ts`가 여전히 활발하게 사용되고 있는지 또는 내부 사용만을 위한 것인지와 관계없이 모든 타입을 사용자에게 공개적으로 노출했습니다.

Astro v5.0은 이 파일을 리팩터링하여 오래된 타입과 내부 타입을 제거합니다. 이 리팩터링은 편집기에 개선 사항을 제공합니다(예: 더 빠른 완성, 더 낮은 메모리 사용량, 더 관련성 있는 완성 옵션). 하지만 이 리팩터링으로 인해 더 이상 공개적으로 사용할 수 없는 타입에 의존하고 있는 일부 프로젝트에서 오류가 발생할 수 있습니다.

#### 무엇을 해야 하나요?

더 이상 접근할 수 없는 타입으로 인해 프로젝트에서 오류가 발생하는 경우 해당 타입을 제거하세요. 이는 대부분 더 이상 사용되지 않고 제거된 API들이지만, 이제 내부용이 된 타입들을 포함하고 있을 수도 있습니다.

<ReadMore>[사용을 위해 공개된 타입](https://github.com/withastro/astro/tree/main/packages/astro/src/types/public)을 참조하세요.</ReadMore>

### 실험적 플래그

다음의 실험적 플래그들은 Astro v5.0에서 제거되었으며 이러한 기능들은 이제 사용할 수 있습니다:

- `env`
- `serverIslands`

또한, 다음의 실험적 플래그들은 제거되었으며 **이제 Astro v5.0에서 기본값 또는 권장되는 동작입니다**.

- `directRenderScript` ([`기본 <script>` 동작](#script-태그가-선언된-그대로-렌더링됩니다)의 주요 변경 사항을 참조하세요.)
- `globalRoutePriority` ([기본 라우트 우선순위 순서](#주입된-라우트와-리디렉션을-위한-경로-우선순위)에 대한 주요 변경 사항을 참조하세요.)
- `contentLayer` (새로운 콘텐츠 레이어 API로 [기존 콘텐츠 컬렉션을 업그레이드](#레거시-v20-콘텐츠-컬렉션-api)하는 방법에 대한 지침을 참조하세요.)

다음의 실험적 플래그들은 제거되었으며 **해당 기능들은 Astro v5.0의 일부가 아닙니다**.

- `contentCollectionsCache`

이전에 이러한 실험적 플래그들을 사용하고 있었다면 제거하고, `env` 설정을 Astro 구성의 루트로 이동하세요:

```js del={5-12} ins={14-16} title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    directRenderScript: true,
    globalRoutePriority: true,
    contentLayer: true,
    serverIslands: true,
    contentCollectionsCache: true,
    env: {
      schema: {...}
    }
  },
  env: {
      schema: {...}
  }
})
```

이 기능들은 모두 Astro v5.0에서 기본적으로 사용 가능합니다.

<ReadMore>이러한 흥미로운 기능들과 더 많은 내용을 [v5.0 블로그 게시물](https://astro.build/blog/astro-5/)에서 확인해보세요.</ReadMore>

## 기본값 변경사항

Astro v5.0에서 일부 기본 동작이 변경되었으며, 이러한 변경 사항을 반영하기 위해 프로젝트 코드를 업데이트해야 할 수 있습니다.

대부분의 경우, 기존 프로젝트의 배포를 검토하고 예상대로 계속 작동하는지 확인한 후 필요에 따라 코드를 업데이트하는 것이 유일하게 필요한 조치입니다. 일부 경우에는 이전 기본 동작을 계속 사용할 수 있도록 하는 구성 설정이 있을 수 있습니다.

### CSRF 보호가 이제 기본값으로 설정됩니다

<SourcePR number="11788" title="change default value of checkOrigin"/>

Astro v4.x에서 `security.checkOrigin`의 기본값은 `false`였습니다. 이전에는 사이트 간 요청 위조(CSRF) 보호를 활성화하기 위해 이 값을 명시적으로 `true`로 설정해야 했습니다.

Astro v5.0에서는 이 옵션의 기본값이 `true`로 변경되었으며, 요청 시 렌더링되는 페이지에서 각 요청이 보낸 URL과 "origin" 헤더가 일치하는지 자동으로 확인합니다.

#### 무엇을 해야 하나요?

이전에 `security.checkOrigin: true`를 구성했던 경우, 이제는 Astro 구성에서 이 줄이 더 이상 필요하지 않습니다. 이것이 이제 기본값이 되었기 때문입니다.

이 동작을 비활성화하려면, 명시적으로 `security.checkOrigin: false`를 설정해야 합니다.

```js title="astro.config.mjs" ins={3-5}
export default defineConfig({
  output: "server",
  security: {
    checkOrigin: false
  }
})
```

<ReadMore>[보안 구성 옵션](/ko/reference/configuration-reference/#security)에 대해 자세히 알아보세요.</ReadMore>

### 주입된 라우트와 리디렉션을 위한 경로 우선순위

<SourcePR number="11798" title="Remove legacy route prioritization"/>

Astro v4.x에서 `experimental.globalRoutePriority`는 주입된 라우트, 파일 기반 라우트 및 리디렉션이 [모든 라우트에 대한 라우트 우선순위 규칙](/ko/guides/routing/#라우트-우선-순위)을 사용하여 우선순위가 지정되도록 보장하는 선택적 플래그였습니다. 이를 통해 특정 유형의 라우트에 자동으로 우선순위를 부여하지 않고 라우트 우선순위 순서를 표준화함으로써 프로젝트의 라우팅을 더 잘 제어할 수 있었습니다.

Astro v5.0에서는 이 실험적 플래그가 제거되었으며, 이것이 Astro의 새로운 기본 동작이 되었습니다: 리디렉션과 주입된 라우트는 이제 파일 기반 프로젝트 라우트와 동등한 우선순위를 가집니다.

이는 이미 Starlight에서 기본 동작이었으며, 업데이트된 Starlight 프로젝트에는 영향을 미치지 않습니다.

#### 무엇을 해야 하나요?

프로젝트에 주입된 라우트나 리디렉션이 포함된 경우, 라우트가 예상대로 페이지 URL을 빌드하고 있는지 확인하시기 바랍니다. 새로운 예상 동작의 예시는 아래와 같습니다.

다음과 같은 라우트가 포함된 프로젝트에서:

- 파일 기반 라우트: `/blog/post/[pid]`
- 파일 기반 라우트: `/[page]`
- 주입된 라우트: `/blog/[...slug]`
- 리디렉션: `/blog/tags/[tag] -> /[tag]`
- 리디렉션: `/posts -> /blog`

다음과 같은 URL이 빌드됩니다 (Astro v4.x의 라우트 우선순위 순서를 따르는 대신):

- `/blog/tags/astro`는 `/tags/[tag]`로 리디렉션됩니다 (주입된 라우트 `/blog/[...slug]` 대신)
- `/blog/post/0`는 파일 기반 라우트 `/blog/post/[pid]`에 의해 빌드됩니다 (주입된 라우트 `/blog/[...slug]` 대신)
- `/posts`는 `/blog`로 리디렉션됩니다 (파일 기반 라우트 `/[page]` 대신)

동일한 라우트 우선순위를 가진 두 라우트가 동일한 URL을 빌드하려고 시도하는 라우트 충돌이 발생하는 경우, Astro는 충돌하는 라우트를 식별하는 경고를 기록합니다.

<ReadMore>[라우트 우선순위 규칙](/ko/guides/routing/#라우트-우선-순위)에 대해 자세히 알아보세요.</ReadMore>

### `<script>` 태그가 선언된 그대로 렌더링됩니다

<SourcePR number="11791" title="Make directRenderScript the default"/>

Astro v4.x에서 `experimental.directRenderScript`는 `.astro` 파일에 선언된 `<scripts>`를 직접 렌더링하는 선택적 플래그였습니다 (TypeScript, `node_modules` 가져오기, 스크립트 중복 제거와 같은 기존 기능 포함). 이 전략은 스크립트가 사용되지 않는 곳에서 실행되는 것을 방지했습니다. 또한 이전에는 조건부로 렌더링된 스크립트는 `is:inline` 지시어가 자동으로 추가되는 것처럼 암시적으로 인라인 처리되었습니다.

Astro 5.0에서는 이 실험적 플래그가 제거되었으며, 이것이 Astro의 새로운 기본 동작이 됩니다: 스크립트가 더 이상 `<head>`로 호이스팅되지 않고, 페이지의 여러 스크립트가 더 이상 함께 번들링되지 않으며, `<script>` 태그가 CSS 스타일링을 방해할 수 있습니다. 또한 조건부로 렌더링된 스크립트는 더 이상 암시적으로 인라인으로 처리되지 않습니다.

#### 무엇을 해야 하나요?

`<script>` 태그를 검토하고 원하는 대로 작동하는지 확인하시기 바랍니다.

이전에 조건부로 렌더링된 `<script>` 태그가 있던 경우, 이전과 동일한 동작을 유지하기 위해 `is:inline` 속성을 추가해야 합니다:

```astro title="src/components/MyComponent.astro" ins="is:inline"
---
type Props = {
  showAlert: boolean
}

const { showAlert } = Astro.props;
---
{
  showAlert && <script is:inline>alert("Some very important code!!")</script>
}
```

<ReadMore>[Astro에서 `script` 태그 사용](/ko/guides/client-side-scripts/)에 대해 자세히 알아보세요.</ReadMore>

## 주요 변경 사항

다음 변경 사항들은 Astro v5.0에서 주요 변경 사항으로 간주됩니다. 주요 변경 사항은 일시적인 하위 호환성을 제공하거나 제공하지 않을 수 있습니다. 이러한 기능들을 사용하고 있었다면, 각 항목에서 권장하는 대로 코드를 업데이트해야 할 수 있습니다.

{/* v4.x 프로젝트의 문서를 참조해야 하는 경우, [v5.0 출시 이전의 (더 이상 유지보수되지 않는) 문서 스냅샷](https://docs-git-v3-docs-unmaintained-astrodotbuild.vercel.app/)을 찾아볼 수 있습니다. */}

### 이름 변경: `<ViewTransitions />` 컴포넌트

<SourcePR number="11980" title="Rename the ViewTransitions component to ClientRouter"/>

Astro 4.x에서는 Astro의 뷰 전환 API에 클라이언트 측 라우팅, 페이지 전환 등을 활성화하기 위한 `<ViewTransitions />` 라우터 컴포넌트가 포함되어 있었습니다.

Astro 5.0에서는 API에서 컴포넌트의 역할을 명확히 하기 위해 이 컴포넌트의 이름을 `<ClientRouter />`로 변경했습니다. 이를 통해 Astro의 `<ClientRouter />` 라우팅 컴포넌트에서 제공하는 기능이 네이티브 CSS 기반 MPA 라우터와 약간 다르다는 점을 더 명확히 알 수 있습니다.

기능상의 변경은 없습니다. 이 컴포넌트는 이름만 변경되었습니다.

#### 무엇을 해야 하나요?

모든 `ViewTransitions` 가져오기와 컴포넌트를 `ClientRouter`로 교체하세요:

```astro title="src/layouts/MyLayout.astro" del={1,7} ins={2,8}
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';

<html>
  <head>
    ...
   <ViewTransitions />
   <ClientRouter />
  </head>
</html>
```

<ReadMore>[Astro의 뷰 전환과 클라이언트 측 라우팅](/ko/guides/view-transitions/)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: TypeScript 구성

<SourcePR number="11859" title="better tsconfig"/>

Astro v4.x에서는 생성된 타입에 의존하는 기능에 대한 타입 추론 및 모듈 정의를 위해 `src/env.d.ts` 파일에 의존했습니다.

대신 Astro 5.0에서는 `.astro/types.d.ts` 파일을 타입 추론에 사용하며, 이제 Astro 타입의 이점을 활용하고 빌드된 파일의 검사를 피하기 위해 `tsconfig.json`에서 `include`와 `exclude`를 설정하는 것을 권장합니다.

`astro sync` 명령은 더 이상 `src/env.d.ts`를 생성하거나 업데이트하지 않습니다. 이는 표준 Astro 프로젝트의 타입 체크에 더 이상 필요하지 않기 때문입니다.

#### 무엇을 해야 하나요?

프로젝트를 Astro의 권장 TypeScript 설정으로 업데이트하려면 기존 `tsconfig.json`에 다음 `include` 및 `exclude` 속성을 추가하세요:

```ts ins={3,4} title="tsconfig.json"
{
  "extends": "astro/tsconfigs/base",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"]
}
```

`src/env.d.ts` 파일은 사용자 정의 설정을 추가했거나 `tsconfig.json` 파일을 사용하지 않는 경우에만 필요합니다.

<ReadMore>[Astro의 TypeScript 설정](/ko/guides/typescript/#설정)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: HTML 양식에 의해 제출된 액션은 더 이상 쿠키 리디렉션을 사용하지 않습니다

<SourcePR number="12373" title="Actions middleware"/>

Astro 4.x에서는 HTML 양식에서 호출된 액션이 쿠키를 사용하여 전달된 결과로 리디렉션을 트리거했습니다. 이로 인해 양식 오류가 크거나 반환값이 큰 경우, 쿠키 기반 저장소의 4KB 제한을 초과하여 문제가 발생했습니다.

Astro 5.0은 이제 어떤 전달 과정 없이 POST 결과로 액션의 결과를 렌더링합니다. 사용자가 페이지를 새로 고침하려고 할 때 "양식 다시 제출 확인" 대화 상자가 표시되지만, 더 이상 액션 반환값에 4KB 제한이 적용되지 않습니다.

#### 무엇을 해야 하나요?

리디렉션에 의존하는 액션 결과 처리를 업데이트해야 하며, 선택적으로 미들웨어를 사용하여 "양식 다시 제출 확인" 대화 상자를 처리할 수 있습니다.

##### 오류 발생 시 이전 경로로 리디렉션

HTML 양식 액션이 다른 경로로 지정된 경우(예: `action={"/success-page" + actions.name}`), Astro는 더 이상 오류 발생 시 이전 경로로 리디렉션하지 않습니다. Astro 컴포넌트에서 리디렉션을 사용하여 이 동작을 수동으로 구현할 수 있습니다. 다음 예시는 성공 시 새로운 경로로 리디렉션하고, 그렇지 않은 경우 현재 페이지에서 오류를 처리합니다:

```astro title="src/pages/newsletter.astro" ins={4-9} del="'/confirmation' + "
---
import { actions } from 'astro:actions';

const result = Astro.getActionResult(actions.newsletter);
if (!result?.error) {
  // 필요한 경우 관련 결과 데이터를 URL에 포함하세요
  // 예시: redirect(`/confirmation?email=${result.data.email}`);
  return redirect('/confirmation');
}
---

<form method="POST" action={'/confirmation' + actions.newsletter}>
  <label>E-mail <input required type="email" name="email" /></label>
  <button>Sign up</button>
</form>
```

##### (선택적) 새로 고침 시 확인 대화 상자 제거

새로 고침 시 "양식 다시 제출 확인" 대화 상자를 처리하거나 세션 간 액션 결과를 유지하기 위해 [미들웨어에서 액션 결과 처리를 사용자 정의](/ko/guides/actions/#고급-세션으로-액션-결과-유지하기)할 수 있습니다.

[Netlify Blob 예시에 설명된 대로](/ko/guides/actions/#고급-세션으로-액션-결과-유지하기) 세션 스토리지 제공자를 사용하는 것을 권장합니다. 하지만 4.X의 쿠키 전달 동작을 선호하고 4KB 크기 제한을 수용할 수 있다면 다음 예시 코드와 같이 패턴을 구현할 수 있습니다:

```ts title="src/middleware.ts"
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';

export const onRequest = defineMiddleware(async (context, next) => {
  // 사전 렌더링된 페이지에 대한 요청 건너뛰기
  if (context.isPrerendered) return next();

	const { action, setActionResult, serializeActionResult } = getActionContext(context);
	// `Astro.getActionResult()`에서 접근할 수 있도록
	// 액션 결과가 쿠키로 전달된 경우 결과 설정하기
	const payload = context.cookies.get('ACTION_PAYLOAD');
	if (payload) {
		const { actionName, actionResult } = payload.json();
		setActionResult(actionName, actionResult);
		context.cookies.delete('ACTION_PAYLOAD', { path: '/' });
		return next();
	}

	// HTML 양식 액션에서 액션이 호출된 경우,
	// 액션 핸들러를 호출하고 결과를 쿠키로 만들어 리디렉션합니다.
	if (action?.calledFrom === 'form') {
		const actionResult = await action.handler();

		context.cookies.set('ACTION_PAYLOAD', {
			actionName: action.name,
			actionResult: serializeActionResult(actionResult),
		}, {
			path: '/',
			httpOnly: true,
			sameSite: 'lax',
			maxAge: 60
		});

		if (actionResult.error) {
		// 오류 발생 시 이전 페이지로 리디렉션
			const referer = context.request.headers.get('Referer');
			if (!referer) {
				throw new Error('Internal: Referer unexpectedly missing from Action POST request.');
			}
			return context.redirect(referer);
		}
		// 성공 시 목적 페이지로 리디렉션
		return context.redirect(context.originPathname);
	}

	return next();
})
```

### 변경됨: `compiledContent()`는 이제 비동기 함수입니다

<SourcePR number="11782" title="Remove TLA by making compiledContent async"/>

Astro 4.x에서는 Markdown 모듈에 최상위 await이 포함되어 있었습니다. 이로 인해 사용자 정의 이미지 서비스와 Markdown의 이미지에서 일부 문제가 발생했으며, Node가 오류 메시지 없이 갑자기 종료되었습니다.

Astro 5.0에서는 Markdown 가져오기의 `compiledContent()` 속성이 비동기 함수가 되어, 콘텐츠를 가져오기 위해 `await`가 필요합니다.

#### 무엇을 해야 하나요?

`compiledContent()`를 호출할 때 `await`을 사용하도록 코드를 업데이트하세요.

```astro title="src/pages/post.astro" del={4} ins={5}
---
import * as myPost from "../blog/post.md";

const content = myPost.compiledContent();
const content = await myPost.compiledContent();
---

<Fragment set:html={content} />
```

<ReadMore>컴파일된 Markdown을 반환하는 [`compiledContent()` 함수](/ko/guides/markdown-content/#markdown-가져오기)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `astro:content`는 더 이상 클라이언트에서 사용할 수 없습니다

<SourcePR number="11827" title="Prevent usage of `astro:content` in the client "/>

Astro 4.x에서는 클라이언트에서 `astro:content` 모듈에 접근하는 것이 가능했습니다.

Astro 5.0은 클라이언트 사용을 위해 의도적으로 노출된 적이 없었기 때문에 이 접근을 제거했습니다. 이러한 방식으로 `astro:content`를 사용하는 것은 제한사항이 있었고 클라이언트 번들의 크기를 부풀렸습니다.

#### 무엇을 해야 하나요?

현재 클라이언트에서 `astro:content`를 사용하고 있다면, 필요한 데이터를 props를 통해 클라이언트 컴포넌트로 전달하세요:

```astro title="src/pages/blog.astro"
---
import { getCollection } from 'astro:content';
import ClientComponent from '../components/ClientComponent';

const posts = await getCollection('blog');
const postsData = posts.map(post => post.data);
---

<ClientComponent posts={postsData} />
```

<ReadMore>[`astro:content` API](/ko/reference/modules/astro-content/)에 대해 자세히 알아보세요.</ReadMore>

### 이름 변경: Shiki `css-variables` 테마 색상 토큰 이름

<SourcePR number="11661" title="Update to new shiki token names"/>

Astro v4.x에서는 Shiki `css-variables` 테마가 코드 블록의 전경색과 배경색을 스타일링하기 위해 각각 `--astro-code-color-text`와 `--astro-code-color-background` 토큰을 사용했습니다.

Astro v5.0은 Shiki v1 기본값과 더 잘 맞추기 위해 이들을 각각 `--astro-code-foreground`와 `--astro-code-background`로 이름을 변경했습니다.

#### 무엇을 해야 하나요?

프로젝트에서 전역 찾기 및 바꾸기를 수행하여 새로운 토큰 이름으로 마이그레이션할 수 있습니다.

```css title="src/styles/global.css" del={2,3} ins={4,5}
:root {
  --astro-code-color-text: #000;
  --astro-code-color-background: #fff;
  --astro-code-foreground: #000;
  --astro-code-background: #fff;
}
```

<ReadMore>[Astro의 구문 강조](/ko/guides/syntax-highlighting/)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: 코드 블록 강조를 위한 내부 Shiki rehype 플러그인

<SourcePR number="11825" title="Refactor createShikiHighlighter"/>

Astro 4.x에서는 Astro의 내부 Shiki rehype 플러그인이 코드 블록을 HTML로 강조했습니다.

Astro 5.0은 이 플러그인을 업데이트하여 코드 블록을 hast로 강조합니다. 이를 통해 Markdown과 MDX 처리가 더 직접적으로 이루어지고 프로젝트 빌드 시 성능이 향상됩니다. 하지만 기존 Shiki 변환기에서 문제가 발생할 수 있습니다.

#### 무엇을 해야 하나요?

`markdown.shikiConfig.transformers`에 전달된 Shiki 변환기를 사용하는 경우, `postprocess` 훅을 사용하지 않도록 해야 합니다. 이 훅은 더 이상 `.md`와 `.mdx` 파일의 코드 블록에서 실행되지 않습니다. (자세한 내용은 [변환기 훅에 대한 Shiki 문서](https://shiki.style/guide/transformers#transformer-hooks)를 참조하세요).

`.mdoc` 파일의 코드 블록과 Astro의 내장 `<Code />` 컴포넌트는 내부 Shiki rehype 플러그인을 사용하지 않으므로 영향을 받지 않습니다.

<ReadMore>[Astro의 구문 강조](/ko/guides/syntax-highlighting/)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: Markdown과 MDX 페이지를 위한 자동 `charset=utf-8` 동작

<SourcePR number="12231" title="Unset charset=utf-8 content-type for md/mdx pages"/>

Astro 4.0에서는 Markdown과 MDX 페이지(`src/pages/`에 위치)가 `Content-Type` 헤더에서 자동으로 `charset=utf-8`으로 응답하여 페이지에서 non-ASCII 문자를 렌더링할 수 있었습니다.

Astro 5.0은 대신 `<meta charset="utf-8">` 태그를 추가하도록 동작이 업데이트되었으며, 이는 Astro의 특별한 `layout` 프런트매터 속성을 사용하지 않는 페이지에만 적용됩니다. MDX 페이지의 경우도 마찬가지로, MDX 콘텐츠가 래핑 `Layout` 컴포넌트를 가져오지 않는 경우에만 Astro가 태그를 추가합니다.

Markdown이나 MDX 페이지가 `layout` 프런트매터 속성을 사용하거나, MDX 페이지 콘텐츠가 래핑 `Layout` 컴포넌트를 가져오는 경우, HTML 인코딩은 지정된 레이아웃 컴포넌트에 의해 대신 처리되며, `<meta charset="utf-8">` 태그는 기본적으로 페이지에 추가되지 않습니다.

#### 무엇을 해야 하나요?

페이지를 올바르게 렌더링하기 위해 `charset=utf-8`이 필요한 경우, 레이아웃 컴포넌트에 `<meta charset="utf-8">` 태그가 포함되어 있는지 확인하세요. 아직 추가하지 않았다면 추가해야 할 수 있습니다.

<ReadMore>[Markdown 레이아웃](/ko/basics/layouts/#markdown-레이아웃)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: Astro 관련 메타데이터가 remark와 rehype 플러그인에 첨부됨

<SourcePR number="11861" title="Clean up Astro metadata in vfile.data"/>

Astro 4.x에서는 remark와 rehype 플러그인의 `vfile.data`에 첨부된 Astro 관련 메타데이터가 서로 다른 위치에 일관성 없는 이름으로 첨부되었습니다.

Astro 5는 API를 정리하여 이제 아래와 같이 메타데이터의 이름이 변경되었습니다:

 - `vfile.data.__astroHeadings` -> `vfile.data.astro.headings`
 - `vfile.data.imagePaths` -> `vfile.data.astro.imagePaths`

`imagePaths`의 타입도 `Set<string>`에서 `string[]`로 업데이트되었습니다. `vfile.data.astro.frontmatter` 메타데이터는 변경되지 않았습니다.

#### 무엇을 해야 하나요?

이러한 API들이 공개 API로 간주되지는 않지만, Astro의 메타데이터를 재사용하고자 하는 remark와 rehype 플러그인에서 접근할 수 있습니다. 이러한 API들을 사용하고 있다면 새로운 위치에서 접근하도록 하세요.

<ReadMore>[Astro에서 Markdown 플러그인 사용하기](/ko/guides/markdown-content/#markdown-플러그인)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: 이미지 엔드포인트 구성

<SourcePR number="11908" title="Allow customising the route of the image endpoint"/>

Astro 4.x에서는 이미지 최적화를 위한 엔드포인트를 `image` 구성에서 설정할 수 있었습니다.

Astro 5.0에서는 `image.endpoint` 설정의 `route`와 `entrypoint`를 사용자 정의할 수 있습니다. 이는 기본 경로 `/_image`가 기존 경로와 충돌하거나 로컬 서버 설정과 충돌하는 특수한 상황에서 유용할 수 있습니다.

#### 무엇을 해야 하나요?

이전에 `image.endpoint`를 사용자 정의했다면, 이 엔드포인트를 새로운 `endpoint.entrypoint` 속성으로 이동하세요. 선택적으로 `route`를 사용자 정의할 수도 있습니다:

```js title="astro.config.mjs" del={5} ins={6-9}
import { defineConfig } from "astro/config";

defineConfig({
  image: {
    endpoint: './src/image-endpoint.ts',
    endpoint: {
      route: "/image",
      entrypoint: "./src/image_endpoint.ts"
    }
  },
})
```

<ReadMore>[이미지 최적화를 위한 엔드포인트 설정](/ko/reference/configuration-reference/#imageendpoint)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `build.client` 및 `build.server`의 동작

<SourcePR number="11916" title="Fix build.client and build.server resolve behaviour" />

Astro v4.x에서는 `build.client`와 `build.server` 옵션이 `outDir` 옵션을 기준으로 상대 경로가 생성되도록 문서화되어 있었지만, 항상 예상대로 작동하지는 않았습니다.

Astro 5.0은 `outDir` 옵션을 기준으로 올바르게 상대 경로가 생성되도록 동작이 수정되었습니다. 예를 들어, `outDir`이 `./dist/nested/`로 설정된 경우 기본값은 다음과 같습니다:

- `build.client`의 빌드 결과물은 `<root>/dist/nested/client/`에 생성됩니다
- `build.server`의 빌드 결과물은 `<root>/dist/nested/server/`에 생성됩니다

이전에는 다음과 같이 잘못된 위치에 생성되었습니다:

- `build.client`의 빌드 결과물은 `<root>/dist/nested/dist/client/`에 생성되었습니다
- `build.server`의 빌드 결과물은 `<root>/dist/nested/dist/server/`에 생성되었습니다

#### 무엇을 해야 하나요?

이전 빌드 경로에 의존하고 있었다면, 프로젝트 코드가 새로운 빌드 경로에 맞게 업데이트되었는지 확인하세요.

<ReadMore>[Astro의 `build` 설정 옵션](/ko/reference/configuration-reference/#빌드-옵션)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: 구성 파일의 JS 의존성은 더 이상 Vite에 의해 처리되지 않습니다

<SourcePR number="11819" title="Set external: true when loading astro config"/>

Astro 4.x에서는 Astro 구성 파일에서 로컬에 연결된 JS 의존성(예: `npm link`, 모노레포 등)을 가져올 때 `import.meta.glob`과 같은 Vite 기능을 사용할 수 있었습니다.

Astro 5는 로컬에 연결된 JS 의존성들을 Vite로 처리하지 않도록 Astro 구성 로딩 과정을 업데이트했습니다. 원본 TypeScript 파일을 내보내는 의존성들은 영향을 받지 않습니다. 대신, 이러한 JS 의존성들은 `node_modules`의 다른 의존성들과 마찬가지로 Node.js 런타임에 의해 일반적인 방식으로 가져와집니다.

이 변경은 로컬에서는 작동하지만 배포 시에는 작동하지 않는 패키지를 테스트한 통합 작성자들 사이에서 혼란을 야기했기 때문에 이루어졌습니다. 또한 Vite가 코드를 ESM으로 요구했기 때문에 CJS 전용 의존성 사용이 제한되었습니다. 이 변경은 JS 의존성에만 영향을 미치지만, 의도치 않은 Vite 특정 사용을 방지하기 위해 가능한 경우 패키지는 원본 TypeScript 대신 JavaScript를 내보내는 것이 권장됩니다. 이는 Astro의 구성 파일 로딩 과정의 구현 세부사항이기 때문입니다.

#### 무엇을 해야 하나요?

로컬에 연결된 JS 의존성이 Astro 프로젝트를 실행하기 전에 빌드되었는지 확인하세요. 그러면 구성 파일 로딩이 이전처럼 작동할 것입니다.

<ReadMore>[Astro의 Vite 구성 설정](/ko/reference/configuration-reference/#vite)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `paginate()`가 반환하는 URL

<SourcePR number="11253" title="Add base to paginate"/>

Astro v4.x에서는 `paginate()`가 반환하는 URL(예: `page.url.next`, `page.url.first` 등)에 Astro 구성의 `base` 값이 포함되지 않았습니다. URL 경로에 구성된 `base` 값을 수동으로 추가해야 했습니다.

Astro 5.0은 `page.url`에 `base` 값을 자동으로 포함합니다.

#### 무엇을 해야 하나요?

`paginate()` 함수를 이러한 URL에 사용하고 있다면, 이제 자동으로 추가되므로 기존의 `base` 값을 제거하세요:

```astro del={16} ins={17}
---
export async function getStaticPaths({ paginate }) {
  const astronautPages = [{
    astronaut: 'Neil Armstrong',
  }, {
    astronaut: 'Buzz Aldrin',
  }, {
    astronaut: 'Sally Ride',
  }, {
    astronaut: 'John Glenn',
  }];
  return paginate(astronautPages, { pageSize: 1 });
}
const { page } = Astro.props;
// `astro.config.mjs`에 `base: /'docs'`가 구성됨
const prev = "/docs" + page.url.prev;
const prev = page.url.prev;
---
<a id="prev" href={prev}>Back</a>
```

<ReadMore>[Astro의 페이지네이션](/ko/guides/routing/#페이지네이션)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: HTML 속성 값이 불리언이 아님

<SourcePR number="11660" title="Fix attribute rendering for boolean values (take 2)"/>

Astro v4.x에서는 HTML로 렌더링될 때 [불리언 HTML 속성](https://developer.mozilla.org/ko/docs/Glossary/Boolean/HTML)이 아닌 속성들의 값이 포함되지 않았을 수 있습니다.

Astro v5.0은 브라우저의 적절한 속성 처리 방식과 일치하도록 값을 `="true"` 또는 `="false"`로 명시적으로 렌더링합니다. 

다음 `.astro` 예시에서 `allowfullscreen`만이 불리언 속성입니다:

```astro
<!-- src/pages/index.astro -->
<!-- `allowfullscreen`는 불리언 속성입니다. -->
<p allowfullscreen={true}></p>
<p allowfullscreen={false}></p>
<!-- `inherit`는 불리언 속성이 *아닙니다.* -->
<p inherit={true}></p>
<p inherit={false}></p>
<!-- `data-*`는 불리언 속성이 아닙니다. -->
<p data-light={true}></p>
<p data-light={false}></p>
```

Astro v5.0은 이제 불리언이 아닌 속성들의 HTML을 렌더링할 때 값이 포함된 전체 데이터 속성을 유지합니다:

```astro del={5,8,10} ins={6,9,11}
<p allowfullscreen></p>
<p></p>

<p inherit="true"></p>
<p inherit></p>
<p inherit="false"></p>

<p data-light></p>
<p data-light="true"></p>
<p></p>
<p data-light="false"></p>
```

#### 무엇을 해야 하나요?

예를 들어 요소를 찾거나 조건부 렌더링을 위해 속성 값에 의존하고 있다면, 불리언이 아닌 속성 값에 맞게 코드를 업데이트하세요:

```js del={1,4} ins={2,5}
el.getAttribute('inherit') === ''
el.getAttribute('inherit') === 'false'

el.hasAttribute('data-light')
el.dataset.light === 'true'
```

<ReadMore>[Astro에서 HTML 속성 사용하기](/ko/reference/astro-syntax/#동적-속성)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `context.locals`에 값 추가

<SourcePR number="11987" title="TODOs"/>

Astro 4.x에서는 미들웨어, API 엔드포인트, 페이지에서 새로운 값을 추가할 때 전체 `locals` 객체를 완전히 대체할 수 있었습니다.

Astro 5.0에서는 기존 `locals` 객체를 삭제하지 않고 값을 추가해야 합니다. 미들웨어, API 엔드포인트, 페이지의 Locals는 더 이상 완전히 덮어쓸 수 없습니다.

#### 무엇을 해야 하나요?

이전에 객체를 덮어쓰던 방식 대신, 이제는 값을 할당해야 합니다:

```js title="src/middleware.js" del={1,5} ins={2,6}
ctx.locals = {
Object.assign(ctx.locals, {
  one: 1,
  two: 2
}
})
```
<ReadMore>[`context.locals`에 데이터 저장하기](/ko/guides/middleware/#contextlocals에-데이터-저장)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `params`는 더 이상 디코딩되지 않음

<SourcePR number="12079" title="decode pathname early, don't decode params"/>

Astro v4.x에서는 `getStaticPath()`에 전달된 `params`가 `decodeURIComponent`를 사용하여 자동으로 디코딩되었습니다.

Astro v5.0에서는 `getStaticPaths`에 전달된 `params`의 값을 더 이상 디코딩하지 않습니다. 필요한 경우 직접 수동으로 디코딩해야 합니다.

#### 무엇을 해야 하나요?

이전에 자동 디코딩에 의존했다면, `params`를 전달할 때 `decodeURI`를 사용하세요.

```astro title="src/pages/[id].astro" del={4} ins={5}
---
export function getStaticPaths() {
  return [
    { params: { id: "%5Bpage%5D" } },
    { params: { id: decodeURI("%5Bpage%5D") } },
  ]
}

const { id } = Astro.params;
---
```

[`decodeURIComponent`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent)는 `/`, `?`, `#` 등과 같이 필요 이상의 문자를 디코딩하므로 `getStaticPaths`에서는 권장되지 않습니다.

<ReadMore>[`params`를 사용한 동적 라우트 생성](/ko/guides/routing/#정적-ssg-모드)에 대해 자세히 알아보세요.</ReadMore>

### 변경됨: `RouteData` 타입이 `IntegrationsRouteData`로 대체됨 (통합 API)

<SourcePR number="11864" title="send `IntegrationRouteData` to integrations"/>

Astro v4.x에서는 `astro:build:ssr`과 `astro:build:done` 훅 내부 `entryPoints`의 타입이 `RouteData`였습니다.

Astro v5.0에서 `entryPoints`의 타입은 이제 `RouteData` 타입의 부분집합인 `IntegrationRouteData`입니다. `isIndex`와 `fallbackRoutes` 필드가 제거되었습니다.

#### 무엇을 해야 하나요?

어댑터를 업데이트하여 `entryPoints`의 타입을 `RouteData`에서 `IntegrationRouteData`로 변경하세요.

```js del={1,4} ins={2,5}
import type {RouteData} from 'astro';
import type {IntegrationRouteData} from "astro"

function useRoute(route: RouteData) {
function useRoute(route: IntegrationRouteData) {
}
```

<ReadMore>[`IntegrationRouteData`에 대한 API 참조](/ko/reference/integrations-reference/#integrationroutedata-타입-참조)를 확인하세요.</ReadMore>

### 변경됨: `distURL`은 이제 배열입니다 (통합 API)

<SourcePR number="11864" title="send `IntegrationRouteData` to integrations"/>

Astro v4.x에서는 `RouteData.distURL`이 `undefined` 또는 `URL`이었습니다.

Astro v5.0에서는 `IntegrationRouteData.distURL`의 형태가 `undefined` 또는 `URL` 배열로 업데이트되었습니다. 이는 특히 `[slug]` 또는 `[...slug]`와 같은 동적 라우트를 사용할 때  하나의 라우트가 디스크에 여러 파일을 생성할 수 있기 때문에 발생하는 이전 오류를 수정한 것입니다.

#### 무엇을 해야 하나요?

코드를 업데이트하여 `IntegrationRouteData.distURL`을 배열로 처리하세요.

```js del={2-4} ins={5-9}
if (route.distURL) {
  if (route.distURL.endsWith('index.html')) {
    // 기존 코드
  }
  for (const url of route.distURL) {
    if (url.endsWith('index.html')) {
      // 기존 코드
    }
  }
}
```

<ReadMore>[`IntegrationRouteData`에 대한 API 참조](/ko/reference/integrations-reference/#integrationroutedata-타입-참조)를 확인하세요.</ReadMore>

### 변경됨: `app.render()`에 전달되는 인수 (어댑터 API)

<SourcePR number="11987" title="TODOs"/>

Astro 4.x에서는 어댑터 API 메서드 `app.render()`가 필수적인 `request`, 옵션 객체 또는 `routeData` 객체, 그리고 `locals`의 세 가지 인수를 받을 수 있었습니다.

Astro 5.0에서는 마지막 두 인수를 `renderOptions`라는 하나의 옵션 인수로 통합했습니다.

#### 무엇을 해야 하나요?

`app.render()`의 두 번째 인수로 `routeData`와 `locals`를 속성으로 포함할 수 있는 객체를 전달하세요.

```js del={1} ins={2}
const response = await app.render(request, routeData, locals);
const response = await app.render(request, {routeData, locals});
```

<ReadMore>[`renderOptions`에 대한 어댑터 API 참조](/ko/reference/adapter-reference/#renderoptions)를 확인하세요.</ReadMore>

### 변경됨: `supportedAstroFeatures`의 속성 (어댑터 API)

<SourcePR number="11806" title="rework supportedAstroFeatures"/>

Astro 4.x에서 어댑터 작성자가 자신의 통합이 지원하는 기능을 지정할 수 있는 `supportedAstroFeatures`는 Astro의 이미지 서비스 중 어떤 것이 지원되는지 지정하는 `assets` 속성을 포함했습니다.

Astro 5.0에서는 이 속성을 어댑터가 내장된 sharp 이미지 서비스와 호환되는지 결정하는 데 사용되는 `sharpImageService` 속성으로 대체합니다.

v5.0은 또한 어댑터의 `supportedAstroFeatures`의 다양한 속성에 대해 새로운 `limited` 값을 추가합니다. 이는 어댑터가 해당 기능과 호환되지만 일부 제한이 있음을 나타냅니다. 이는 모든 경우나 모든 옵션에서는 아니지만 기능을 지원하는 어댑터에 유용합니다.

또한 어댑터의 `supportedAstroFeatures`의 다양한 속성 값은 이제 `support`와 `message` 속성을 가진 객체가 될 수 있습니다. `message` 속성의 내용은 어댑터가 기능과 호환되지 않을 때 Astro CLI에서 도움이 되는 메시지를 표시합니다. 이는 특히 새로운 `limited` 값과 함께 사용자에게 지원이 제한되는 이유를 설명하는 데 유용합니다.

#### 무엇을 해야 하나요?

만약 `assets` 속성을 사용했다면, 이는 더 이상 사용할 수 없으므로 제거하세요. 어댑터가 내장된 sharp 이미지 서비스를 지원한다고 지정하려면 이를 `sharpImageService`로 대체하세요.

또한 새로운 `limited` 옵션으로 지원되는 기능을 업데이트하고 어댑터의 지원에 대한 메시지를 포함할 수 있습니다.

```ts title="my-adapter.mjs" del={2-6} ins={7-10}
supportedAstroFeatures: {
  assets: {
    supportKind: "stable",
    isSharpCompatible: true,
    isSquooshCompatible: true,
  },
  sharpImageService: {
    support: "limited",
    message: 'This adapter supports the built-in sharp image service, but with some limitations.'
  }
}
```

<ReadMore>[어댑터에서 지원되는 Astro 기능 지정하기](/ko/reference/adapter-reference/#astro-기능)에 대해 자세히 알아보세요.</ReadMore>

### 제거됨: 개발 툴바 앱의 정의 형태는 더 이상 사용되지 않음 (개발 툴바 API)

<SourcePR number="11987" title="Remove deprecated dev toolbar app shape"/>

Astro 4.x에서는 개발 툴바 앱을 만들 때 이전에 지원 중단된 `addDevToolbarApp(string);` 시그니처를 여전히 사용할 수 있었습니다. 그런 다음 앱을 정의하는 `id`, `title`, `icon` 속성들은 앱의 `entrypoint`의 기본 내보내기를 통해 사용할 수 있었습니다.

Astro 5.0에서는 이 옵션을 완전히 제거하고, 대신 통합에서 개발 툴바 앱을 정의할 때 현재의 객체 형태를 사용합니다. 이는 더 직관적이고 툴바 앱이 제대로 로드되지 않을 때 Astro가 더 나은 오류를 제공할 수 있도록 합니다.

#### 무엇을 해야 하나요?

지원 중단된 형태를 사용하고 있었다면, 개발 툴바 앱을 새로운 형태로 업데이트하세요:

```js title="my-integration.mjs" del={1-2} ins={4-10}
// 이전 형태
addDevToolbarApp("./my-dev-toolbar-app.mjs");

// 새 형태
addDevToolbarApp({
  id: "my-app",
  name: "My App",
  icon: "<svg>...</svg>",
  entrypoint: "./my-dev-toolbar-app.mjs",
});
```

```js title="my-dev-toolbar-app.mjs" del={2-4}
export default {
  id: 'my-dev-toolbar-app',
  title: 'My Dev Toolbar App',
  icon: '🚀',
  init() {
    // ...
  }
}
```

<ReadMore>[개발 툴바 API를 사용하여 Astro용 개발 툴바 앱 개발하기](/ko/reference/dev-toolbar-app-reference/)에 대해 자세히 알아보세요.</ReadMore>

### 제거됨: `create-astro`에서 TypeScript 구성

<SourcePR number="12083" title="create-astro updates"/>

Astro v4.x에서는 `create astro`를 사용하여 새 프로젝트를 생성할 때 질문에 답하거나 원하는 TypeScript 설정과 함께 관련된 `--typescript` 플래그를 전달하여 Astro의 세 가지 TypeScript 설정 중 하나를 선택할 수 있었습니다.

Astro 5.0은 `create astro` CLI 명령을 업데이트하여 TypeScript 질문과 `--typescript` 플래그를 제거했습니다. "strict" 프리셋이 이제 명령줄로 생성된 모든 새 프로젝트의 기본값이 되었으며 더 이상 이 시점에서 이를 사용자 정의할 수 없습니다. 하지만 TypeScript 템플릿은 여전히 `tsconfig.json`에서 수동으로 변경할 수 있습니다.

#### 무엇을 해야 하나요?

`create-astro`에서 `--typescript` 플래그를 사용하고 있었다면, 명령에서 제거하세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```diff lang=shell
  -npm create astro@latest -- --template <example-name> --typescript strict
  +npm create astro@latest -- --template <example-name>
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```diff lang=shell
  -pnpm create astro@latest --template <example-name> --typescript strict
  +pnpm create astro@latest --template <example-name>
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```diff lang=shell
  -yarn create astro --template <example-name> --typescript strict
  +yarn create astro --template <example-name>
  ```
  </Fragment>
</PackageManagerTabs>

<ReadMore>[사용 가능한 모든 `create astro` 명령 플래그](https://github.com/withastro/astro/blob/main/packages/create-astro/README.md)를 확인하세요.</ReadMore>

## 커뮤니티 리소스

Astro v5.0에 대한 좋은 리소스를 알고 계신가요? [이 페이지를 편집](https://github.com/withastro/docs/edit/main/src/content/docs/en/guides/upgrade-to/v5.mdx)하여 아래에 링크를 추가해주세요!

## 알려진 문제

[Astro의 GitHub issues](https://github.com/withastro/astro/issues/)에서 보고된 이슈를 확인하거나 직접 이슈를 제출해주세요.
